package com.fahai.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateUtil {

    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();

    private static final Object object = new Object();

    /**
     * 获取SimpleDateFormat
     *
     * @param pattern 日期格式
     * @return SimpleDateFormat对象
     * @throws RuntimeException 异常：非法日期格式
     */
    private static SimpleDateFormat getDateFormat(String pattern) throws RuntimeException {
        SimpleDateFormat dateFormat = threadLocal.get();
        if (dateFormat == null) {
            synchronized (object) {
                if (dateFormat == null) {
                    dateFormat = new SimpleDateFormat(pattern);
                    dateFormat.setLenient(false);
                    threadLocal.set(dateFormat);
                }
            }
        }
        dateFormat.applyPattern(pattern);
        return dateFormat;
    }

    /**
     * 获取精确的日期
     *
     * @param timestamps 时间long集合
     * @return 日期
     */
    private static Date getAccurateDate(List<Long> timestamps) {
        Date date = null;
        long timestamp = 0;
        Map<Long, long[]> map = new HashMap<Long, long[]>();
        List<Long> absoluteValues = new ArrayList<Long>();

        if (timestamps != null && timestamps.size() > 0) {
            if (timestamps.size() > 1) {
                for (int i = 0; i < timestamps.size(); i++) {
                    for (int j = i + 1; j < timestamps.size(); j++) {
                        long absoluteValue = Math.abs(timestamps.get(i) - timestamps.get(j));
                        absoluteValues.add(absoluteValue);
                        long[] timestampTmp = {timestamps.get(i), timestamps.get(j)};
                        map.put(absoluteValue, timestampTmp);
                    }
                }

                // 有可能有相等的情况。如2012-11和2012-11-01。时间戳是相等的。此时minAbsoluteValue为0
                // 因此不能将minAbsoluteValue取默认值0
                long minAbsoluteValue = -1;
                if (!absoluteValues.isEmpty()) {
                    minAbsoluteValue = absoluteValues.get(0);
                    for (int i = 1; i < absoluteValues.size(); i++) {
                        if (minAbsoluteValue > absoluteValues.get(i)) {
                            minAbsoluteValue = absoluteValues.get(i);
                        }
                    }
                }

                if (minAbsoluteValue != -1) {
                    long[] timestampsLastTmp = map.get(minAbsoluteValue);

                    long dateOne = timestampsLastTmp[0];
                    long dateTwo = timestampsLastTmp[1];
                    if (absoluteValues.size() > 1) {
                        timestamp = Math.abs(dateOne) > Math.abs(dateTwo) ? dateOne : dateTwo;
                    }
                }
            } else {
                timestamp = timestamps.get(0);
            }
        }

        if (timestamp != 0) {
            date = new Date(timestamp);
        }
        return date;
    }


    /**
     * 将日期字符串转化为日期。失败返回null。
     *
     * @param date    日期字符串
     * @param pattern 日期格式
     * @return 日期
     */
    public static Date StringToDate(String date, String pattern) {
        Date myDate = null;
        if (date != null) {
            try {
                myDate = getDateFormat(pattern).parse(date);
            } catch (Exception e) {
            }
        }
        return myDate;
    }

    /**
     * 将日期转化为日期字符串。失败返回null。
     *
     * @param date    日期
     * @param pattern 日期格式
     * @return 日期字符串
     */
    public static String DateToString(Date date, String pattern) {
        String dateString = null;
        if (date != null) {
            try {
                dateString = getDateFormat(pattern).format(date);
            } catch (Exception e) {
            }
        }
        return dateString;
    }

    /**
     * 时间戳转字符串
     * @param timestamp
     * @param pattern
     * @return
     */
    public static String TimeStampToString(Timestamp timestamp,String pattern){
        DateFormat sdf = new SimpleDateFormat(pattern);
        String timeStampStr = null;
        try{
            if(null==timestamp){
                return null;
            }else{
                timeStampStr = sdf.format(timestamp);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return timeStampStr;
    }

    /**
     * 字符串转时间戳
     * @return
     */
    public static Timestamp StringToTimeStamp(String timeStr,String pattern){
        DateFormat sdf = new SimpleDateFormat(pattern);
        Timestamp timestamp = null;
        try{
            Date date = sdf.parse(timeStr);
            timestamp = new Timestamp(date.getTime());
//            Timestamp.valueOf(timeStr);
        }catch (Exception e){
            e.printStackTrace();
        }
        return timestamp;
    }

    /**
     * 将日期字符串转化为另一日期字符串。失败返回null。
     *
     * @param date        旧日期字符串
     * @param oldPattern 旧日期格式
     * @param newPattern  新日期格式
     * @return 新日期字符串
     */
    public static String StringToString(String date, String oldPattern, String newPattern) {
        return DateToString(StringToDate(date, oldPattern), newPattern);
    }

    /**
     * 获取给的日期的前一天。
     * @return 前一天的日期
     */
    public static String getYesterdayStr() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);     //这里测试为前两天的,
        date = calendar.getTime();
        return DateToString(date, "yyyy-MM-dd");
    }

    public static String getCurrentTimeStr() {
        Date date = new Date();
        String currentDate = DateToString(date, "yyyy-MM-dd+HH:mm:ss");
        return currentDate;
    }

    public static String getCurrentTimeStr2() {
        Date date = new Date();
        String currentDate = DateToString(date, "yyyy-MM-dd_HH-mm-ss");
        return currentDate;
    }
    // 获得当天0点时间
    public static Date getTodayStart() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

//   获取今日的最晚时间
    public static Date getTodayEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }

    // 获得昨天0点时间
    public static Date getYesterdayStart() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getTodayStart().getTime()-3600*24*1000);
        return cal.getTime();
    }

    // 获得昨天24点时间
    public static Date getYesterdayEnd() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getTodayStart().getTime()-1);
        return cal.getTime();
    }

    // 获得本月第一天0点时间
    public static Date getThisMonthStart() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }

    // 获得上月第一天0点时间
    public static Date getLastMonthStart() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisMonthStart());
        cal.add(Calendar.MONTH, -1);
        return cal.getTime();
    }

    // 获得上月最后一天24点时间
    public static Date getLastMonthEnd() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getThisMonthStart().getTime()-1000);
        return cal.getTime();
    }

    public static String strToDateFormat(String date)  {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmsss");

        Date newDate=new Date();

        try {

            formatter.setLenient(false);

            newDate=formatter.parse(date);

            formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        }catch (ParseException  p){

             p.printStackTrace();
        }

        return formatter.format(newDate);
    }

    /**
     *返回当前时间戳
     * @return 当前时间戳
     */
    public static Timestamp getCurrentTimestamp(){
        return    new Timestamp(System.currentTimeMillis());
    }


    /**
     * 返回追加00：00：00后的开始时间
     * @param d
     * @return
     */
    public static String getStartTimeStr(String d){
        if(d!=null&&(!"".equals(d))){
            return d+=" 00:00:00";
        }else{
            return "";
        }
    }
    /**
     * 返回追加 23:59:59后的结束时间
     * @param d
     * @return
     */
    public static String getEndTimeStr(String d){
        if(d!=null&&(!"".equals(d))){
            return d+=" 23:59:59";
        }else{
            return "";
        }
    }


}